introduction to rmarkdown
Anna Krystalli
Instituto de EcologĂa, UNAM 31 Aug. 2016
introduction
markdown .md
stripped down html
intended to be as easy-to-read and easy-to-write as possible.
intended for one purpose: to be used as a format for writing for the web.
syntax is very small, corresponding only to a very small subset of HTML tags.
focus on communicating & disseminating
formatting handled automatically
clean and legible across platforms and outputs
rmarkdown .Rmd
rmarkdown integrates:
– a documentantion language (.md)
with:
– a programming language (R)
enables literate programming
single document to integrate data analysis with textual representations, linking data, code, and text
outputs
it’s already everywhere!
Rmarkdown & reproducibility
Computational science has led to exciting new developments:
Technology is increasing data collection throughput; data are more complex and highdimensional
Existing databases can be merged to become bigger databases
Computing power allows more sophisticated analyses, even on “small” data
For every field “X” there is a “Computational X”
Increasing computational complexity of analyses:
has exposed limitations in our ability to evaluate published findings.
Even basic analyses difficult to describe
Errors more easily introduced into long analysis pipelines
Knowledge transfer is inhibited
Results are difficult to replicate or reproduce
Complicated analyses cannot be trusted
calls for reproducibility
Reproducibility has the potential to serve as a minimum standard for judging scientific claims when full independent replication of a study is not possible.
fully scripted analyses
make code and data available
a reproducible workflow
VIDEO
reproducibility limitations
evidence based science
evdence needs:
documenting
linking
communicating
rmarkdown can integrate tools, processes and outputs into evidence streams that are easily shareable
at all stages of scientific process
Science and the web
the web is for sharing!
why sharing is important
To help solve these problems, we make a number of suggestions including providing blog posts or videos to explain new methods in less technical terms, encouraging reproducibility and code sharing, making wiki-style pages summarising the literature on popular methods, more careful consideration and testing of whether a method is appropriate for a given question/data set, increased collaboration, and a shift from publishing purely novel methods to publishing improvements to existing methods and ways of detecting biases or testing model fit. Many of these points are applicable across methods in ecology and evolution, not just phylogenetic comparative methods.
Let’s go have a look
Open your first .Rmd!!
Elements of .Rmd
themes
md basics
text
normal text
normal text
*italic text*
italic text
**bold text**
bold text
***bold italic text***
bold italic text
superscript^2^
superscript2
~~strikethrough~~
strikethrough
quotes & code
> this text will be quoted
this text will be quoted
`this text will appear as code` inline
this text will appear as code inline
a <- 10
the value of parameter *a* is `r a`
the value of parameter a is 10
images


resize images
<img src="assets/cheat.png" width="200px" />
basic tables
Table Header | Second Header
------------- | -------------
Cell 1 | Cell 2
Cell 3 | Cell 4
Cell 1
Cell 2
Cell 3
Cell 4
online .md table converter
links
[Download R](http://www.r-project.org/)
[RStudio](http://www.rstudio.com/)
Download R
RStudio
chunks
R code chunks can be used as a means render R output into documents or to simply display code for illustration
set default options
knitr::opts_chunk$set(echo = TRUE, warning = F, message = F)
Exercise
your mission
create your first .Rmd!
choose some data eg:
show us some data in a table
plot some data
write a bit about what you did
publish it on rpubs. Add you link to our googledoc
see my example: beavers! html - raw .Rmd
CiMjICoqaW50cm9kdWN0aW9uIHRvIGBybWFya2Rvd25gKioKCiMjIyAqKkFubmEgS3J5c3RhbGxpKioKIyMjIyMgKioqSW5zdGl0dXRvIGRlIEVjb2xvZ8OtYSwgVU5BTSAzMSBBdWcuIDIwMTYqKioKCjxicj4KCiMjIyMjIyA8aHR0cHM6Ly9hbm5ha3J5c3RhbGxpLmdpdGh1Yi5pby9VTkFNL3JtYXJrZG93bi5uYi5odG1sPgoKIyMjIyMjIFtcQGFubmFrcnlzdGFsbGldKGh0dHBzOi8vdHdpdHRlci5jb20vYW5uYWtyeXN0YWxsaSkgfCBhbm5ha3J5c3RhbGxpQGdvb2dsZW1haWwuY29tCgoKPGJyPgo8YnI+CgojICoqaW50cm9kdWN0aW9uKioKCiMjICoqbWFya2Rvd24gYC5tZGAqKgoKIyMjIyBzdHJpcHBlZCBkb3duICoqYGh0bWxgKioKCjxicj4KCi0gIGludGVuZGVkIHRvIGJlIGFzICoqZWFzeS10by1yZWFkKiogYW5kICoqZWFzeS10by13cml0ZSoqIGFzIHBvc3NpYmxlLgotICBpbnRlbmRlZCBmb3Igb25lIHB1cnBvc2U6IHRvIGJlIHVzZWQgYXMgYSAqKmZvcm1hdCBmb3Igd3JpdGluZyBmb3IgdGhlIHdlYi4qKgotICBzeW50YXggaXMgdmVyeSBzbWFsbCwgY29ycmVzcG9uZGluZyBvbmx5IHRvIGEgdmVyeSBzbWFsbCBzdWJzZXQgb2YgSFRNTCB0YWdzLgoKPGJyPgoKIyMgKipmb2N1cyBvbiBjb21tdW5pY2F0aW5nICYgZGlzc2VtaW5hdGluZyoqCgo8YnI+CgotIGZvcm1hdHRpbmcgaGFuZGxlZCBhdXRvbWF0aWNhbGx5Ci0gY2xlYW4gYW5kIGxlZ2libGUgYWNyb3NzIHBsYXRmb3JtcyBhbmQgb3V0cHV0cwoKIyMgKipzdHJ1Y3R1cmUgb2YgYSB3ZWJzaXRlKioKCiFbXShhc3NldHMvaHRtbC1jc3MtamF2YXNjcmlwdC5wbmcpCgojIyAqKnJtYXJrZG93biBgLlJtZGAqKgoKIyMjIyBgcm1hcmtkb3duYCBpbnRlZ3JhdGVzOgoK4oCTICAqKmEgZG9jdW1lbnRhbnRpb24gbGFuZ3VhZ2UgKGAubWRgKSoqCgp3aXRoOgoK4oCTICAqKmEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgKGBSYCkqKgoKPGJyPgoKIyMjIyBlbmFibGVzIGxpdGVyYXRlIHByb2dyYW1taW5nCgpzaW5nbGUgZG9jdW1lbnQgdG8gaW50ZWdyYXRlIGRhdGEgYW5hbHlzaXMgd2l0aCB0ZXh0dWFsIHJlcHJlc2VudGF0aW9ucywgKipsaW5raW5nIGRhdGEsIGNvZGUsIGFuZCB0ZXh0KioKCjxicj4KCiMjICoqb3V0cHV0cyoqCgo8aW1nIHNyYz0iYXNzZXRzL1JNYXJrZG93bk91dHB1dEZvcm1hdHMucG5nIiwgd2lkdGg9IjQwMHB4Ii8+Cgo8YnI+CgojIyAqKml0J3MgYWxyZWFkeSBldmVyeXdoZXJlISoqCgotIFtnaXRodWIgUkVBRE1FczsgZWcgck9wZW5zY2kgdGF4aXNlIFJFQURNRV0oaHR0cHM6Ly9naXRodWIuY29tL3JvcGVuc2NpL3RheGl6ZSkKCi0gW3N0YWNrb3ZlcmZsb3c6IGVnIHBsb3QgY29vcmRpbmF0ZXMgb24gYSBtYXBdKGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMjMxMzA2MDQvci1wbG90LWNvb3JkaW5hdGVzLW9uLW1hcCkKICAgIAotIFtnaXRodWIuaW8gd2Vic2l0ZXM6IGVnIEFuZHkgU291dGgncyBibG9nXShodHRwOi8vYW5keXNvdXRoLmdpdGh1Yi5pby9ibG9nLXNldHVwLykKCjxicj4KPGJyPgoKKioqCgojICoqYFJtYXJrZG93bmAgJiByZXByb2R1Y2liaWxpdHkqKgoKPGJyPgoKIyMge2RhdGEtYmFja2dyb3VuZD0iaHR0cDovLzQ5Lm1lZGlhLnR1bWJsci5jb20vN2RhZWZmMWQ0MTBiZjVkY2U0YzBiMzBjNDBiNDRmNzcvdHVtYmxyX245ZHk5b2xMSmUxcWF2M3VzbzJfNTAwLmdpZiJ9Cgo+IDxzcGFuIHN0eWxlPSJjb2xvcjpibGFjayI+IENvbXB1dGF0aW9uYWwgc2NpZW5jZSBoYXMgbGVkIHRvIGV4Y2l0aW5nIG5ldyBkZXZlbG9wbWVudHM6PC9zcGFuPgoKLSAgPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIj48Yj4gVGVjaG5vbG9neSBpcyBpbmNyZWFzaW5nIGRhdGEgY29sbGVjdGlvbiB0aHJvdWdocHV0OyBkYXRhIGFyZSBtb3JlIGNvbXBsZXggYW5kIGhpZ2hkaW1lbnNpb25hbDwvYj48L3NwYW4+Ci0gIDxzcGFuIHN0eWxlPSJjb2xvcjpibGFjayI+PGI+IEV4aXN0aW5nIGRhdGFiYXNlcyBjYW4gYmUgbWVyZ2VkIHRvIGJlY29tZSBiaWdnZXIgZGF0YWJhc2VzPC9iPjwvc3Bhbj4KLSAgPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIj48Yj4gQ29tcHV0aW5nIHBvd2VyIGFsbG93cyBtb3JlIHNvcGhpc3RpY2F0ZWQgYW5hbHlzZXMsIGV2ZW4gb24gInNtYWxsIiBkYXRhPC9iPjwvc3Bhbj4KLSAgPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIj48Yj4gRm9yIGV2ZXJ5IGZpZWxkICJYIiB0aGVyZSBpcyBhICJDb21wdXRhdGlvbmFsIFgiPC9iPjwvc3Bhbj4KCjxicj4KCiMjIHtkYXRhLWJhY2tncm91bmQ9Imh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9CaWxsTWlsbHMvc2NpZW5jZVhweXRob24vZ2gtcGFnZXMvaW1nL2RlYnVnZ2luZy5naWYifQoKPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIj48Yj5JbmNyZWFzaW5nIGNvbXB1dGF0aW9uYWwgY29tcGxleGl0eSBvZiBhbmFseXNlczo8L2I+PC9zcGFuPgoKPiA8c3BhbiBzdHlsZT0iY29sb3I6YmxhY2siPmhhcyBleHBvc2VkIGxpbWl0YXRpb25zIGluIG91ciBhYmlsaXR5IHRvIGV2YWx1YXRlIHB1Ymxpc2hlZCBmaW5kaW5ncy48L3NwYW4+CgoKLSA8c3BhbiBzdHlsZT0iY29sb3I6YmxhY2siPjxiPkV2ZW4gYmFzaWMgYW5hbHlzZXMgZGlmZmljdWx0IHRvIGRlc2NyaWJlPC9iPjwvc3Bhbj4KCi0gPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIj48Yj5FcnJvcnMgbW9yZSBlYXNpbHkgaW50cm9kdWNlZCBpbnRvIGxvbmcgYW5hbHlzaXMgcGlwZWxpbmVzPC9iPjwvc3Bhbj4KCi0gPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIj48Yj5Lbm93bGVkZ2UgdHJhbnNmZXIgaXMgaW5oaWJpdGVkPC9iPjwvc3Bhbj4KCi0gPHNwYW4gc3R5bGU9ImNvbG9yOmJsYWNrIj48Yj5SZXN1bHRzIGFyZSBkaWZmaWN1bHQgdG8gcmVwbGljYXRlIG9yIHJlcHJvZHVjZTwvYj48L3NwYW4+CgotIDxzcGFuIHN0eWxlPSJjb2xvcjpibGFjayI+PGI+Q29tcGxpY2F0ZWQgYW5hbHlzZXMgY2Fubm90IGJlIHRydXN0ZWQ8L2I+PC9zcGFuPgoKPGJyPgo8YnI+CgojIyAqKmNhbGxzIGZvciByZXByb2R1Y2liaWxpdHkqKgoKPGJyPgoKPiAgUmVwcm9kdWNpYmlsaXR5IGhhcyB0aGUgcG90ZW50aWFsIHRvIHNlcnZlIGFzIGEgbWluaW11bSBzdGFuZGFyZCBmb3IganVkZ2luZyBzY2llbnRpZmljIGNsYWltcyB3aGVuIGZ1bGwgaW5kZXBlbmRlbnQgcmVwbGljYXRpb24gb2YgYSBzdHVkeSBpcyBub3QgcG9zc2libGUuCgojIyAKCi0gKipmdWxseSBzY3JpcHRlZCBhbmFseXNlcyoqCi0gKiptYWtlIGNvZGUgYW5kIGRhdGEgYXZhaWxhYmxlKioKCjxpbWcgc3JjPSJhc3NldHMvcmVwcm9fd29ya2Zsb3cucG5nIiB3aWR0aD0iNTAwcHgiIC8+Cgo8YnI+CgojIyAqKmEgcmVwcm9kdWNpYmxlIHdvcmtmbG93KioKCjxpZnJhbWUgd2lkdGg9IjU2MCIgaGVpZ2h0PSIzMTUiIHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvczNKbGRLb0EwenciIGZyYW1lYm9yZGVyPSIwIiBhbGxvd2Z1bGxzY3JlZW4+PC9pZnJhbWU+Cgo8YnI+CgojIyAqKnJlcHJvZHVjaWJpbGl0eSBsaW1pdGF0aW9ucyoqCgotIHRvcCBkb3duCi0gZG93bnN0cmVhbSAocG9zdCBwdWJsaWNhdGlvbikKLSB1bHRpbWF0ZWx5IGRvZXMgbm90IGFkZHJlc3MgdGhlIGtleSBxdWVzdGlvbjogCgogICAgPiAqKmNhbiB3ZSB0cnVzdCB0aGVzZSByZXN1bHRzPyoqCgo8YnI+CgojIyAqKmV2aWRlbmNlIGJhc2VkIHNjaWVuY2UqKgoKZXZkZW5jZSBuZWVkczoKCi0gKipkb2N1bWVudGluZyoqCi0gKipsaW5raW5nKioKLSAqKmNvbW11bmljYXRpbmcqKgoKPGJyPgoKYHJtYXJrZG93bmAgY2FuIGludGVncmF0ZSAqKnRvb2xzLCBwcm9jZXNzZXMqKiBhbmQgKipvdXRwdXRzKiogaW50byAqKmV2aWRlbmNlIHN0cmVhbXMqKiB0aGF0IGFyZSBlYXNpbHkgc2hhcmVhYmxlCgo+IGF0IGFsbCBzdGFnZXMgb2Ygc2NpZW50aWZpYyBwcm9jZXNzCgo8YnI+CgojIyAqKnNpbXBsZSB0b29sczoqKiAKIyMjIGxvdyBoYW5naW5nIGZydWl0CgotIGJlZ2luIGF0IHRoZSBzdGFydCBvZiB0aGUgcHJvY2VzcwotIGRvY3VtZW50ICYgaW50ZXJsaW5rIGV2aWRlbmNlIHN0cmVhbXMKLSBleHBsb3JlIGFuZCBjb21tdW5pY2F0ZSEKCj4gZW1wb3dlciB5b3VyIGNvZGUgYW5kIGRhdGEKCjxicj4KCiMjICoqU2NpZW5jZSBhbmQgdGhlIHdlYioqCgojIyMjICoqdGhlIHdlYiBpcyBmb3Igc2hhcmluZyEqKgoKPGltZyBzcmM9ImFzc2V0cy93d3cuanBnIiB3aWR0aD0iNjUwcHgiIC8+CgoKIyMjIyMjIFtFeGVjdXRpdmUgc3VtbWFyeSBvZiB0aGUgZmlyc3QgZXZlciB3ZWJzaXRlXShodHRwOi8vaW5mby5jZXJuLmNoL2h5cGVydGV4dC9XV1cvU3VtbWFyeS5odG1sKQoKPGJyPgoKIyMgKip3aHkgc2hhcmluZyBpcyBpbXBvcnRhbnQqKgoKPGltZyBzcmM9ImFzc2V0cy9wZ2xzLnBuZyIgd2lkdGg9IjM1MHB4IiAvPgoKPiA8c21hbGw+IFRvIGhlbHAgc29sdmUgdGhlc2UgcHJvYmxlbXMsIHdlIG1ha2UgYSBudW1iZXIgb2Ygc3VnZ2VzdGlvbnMgaW5jbHVkaW5nIHByb3ZpZGluZyBibG9nIHBvc3RzIG9yIHZpZGVvcyB0byBleHBsYWluIG5ldyBtZXRob2RzIGluIGxlc3MgdGVjaG5pY2FsIHRlcm1zLCBlbmNvdXJhZ2luZyByZXByb2R1Y2liaWxpdHkgYW5kIGNvZGUgc2hhcmluZywgbWFraW5nIHdpa2ktc3R5bGUgcGFnZXMgc3VtbWFyaXNpbmcgdGhlIGxpdGVyYXR1cmUgb24gcG9wdWxhciBtZXRob2RzLCBtb3JlIGNhcmVmdWwgY29uc2lkZXJhdGlvbiBhbmQgdGVzdGluZyBvZiB3aGV0aGVyIGEgbWV0aG9kIGlzIGFwcHJvcHJpYXRlIGZvciBhIGdpdmVuIHF1ZXN0aW9uL2RhdGEgc2V0LCBpbmNyZWFzZWQgY29sbGFib3JhdGlvbiwgYW5kIGEgc2hpZnQgZnJvbSBwdWJsaXNoaW5nIHB1cmVseSBub3ZlbCBtZXRob2RzIHRvIHB1Ymxpc2hpbmcgaW1wcm92ZW1lbnRzIHRvIGV4aXN0aW5nIG1ldGhvZHMgYW5kIHdheXMgb2YgZGV0ZWN0aW5nIGJpYXNlcyBvciB0ZXN0aW5nIG1vZGVsIGZpdC4gTWFueSBvZiB0aGVzZSBwb2ludHMgYXJlIGFwcGxpY2FibGUgYWNyb3NzIG1ldGhvZHMgaW4gZWNvbG9neSBhbmQgZXZvbHV0aW9uLCBub3QganVzdCBwaHlsb2dlbmV0aWMgY29tcGFyYXRpdmUgbWV0aG9kcy48L3NtYWxsPgoKPGJyPgoKIyMgKipleGFtcGxlcyoqCgojIyMjIFtyZXBvcnRdKGZpbGU6Ly8vVXNlcnMvQW5uYS9Hb29nbGUlMjBEcml2ZS9iaXJkJTIwdHJhaXQlMjBuZXR3b3Jrcy9vdXRwdXRzL1JlcG9ydHMvUmVzdWx0cy9Db3JOZXR3b3JrX3Bsb3RzLmh0bWwpCgojIyMjIFtjb2RlIGRvY3VtZW50YXRpb25dKGh0dHA6Ly9ycHVicy5jb20vYW5uYWtyeXN0YWxsaS8xMjMxOTYpCgojIyMjIFttZXRob2QgY29sbGF0aW9uXShmaWxlOi8vL1VzZXJzL0FubmEvR29vZ2xlJTIwRHJpdmUvYmlyZCUyMHRyYWl0JTIwbmV0d29ya3Mvb3V0cHV0cy9SZXBvcnRzL3dvcmtmbG93JTIwZG9jdW1lbnRhdGlvbi9IaWVyYXJjaGljYWwlMjBOZXR3b3Jrcy5odG0pCgojIyMjIFtpbnRlcmFjdGl2ZSBkb2N1bWVudHNdKGh0dHA6Ly9ycHVicy5jb20vYW5uYWtyeXN0YWxsaS8xNjE3NjApCgojIyMjIFtwcmVzZW50YXRpb25zXShodHRwOi8vcnB1YnMuY29tL2FubmFrcnlzdGFsbGkvMTMzMzkxKQoKKioqCgo8YnI+Cjxicj4KCgoKIyBMZXQncyBnbyBoYXZlIGEgbG9vawoKT3BlbiB5b3VyIGZpcnN0IGAuUm1kYCEhCgo8aW1nIHNyYz0iYXNzZXRzL25ld21kLmdpZiIgd2lkdGg9IjUwMHB4IiAvPgoKKioqCgo8YnI+Cjxicj4KCiMgKipFbGVtZW50cyBvZiAuUm1kKioKCjxicj4KCiMjICoqWUFNTCBoZWFkZXIqKgoKIyMjIG91dHB1dHMKPGltZyBzcmM9ImFzc2V0cy9vdXRwdXRzLnBuZyIgd2lkdGg9IjUwMHB4IiAvPgoKIyMgKip0aGVtZXMqKgoKPGltZyBzcmM9ImFzc2V0cy90aGVtZS5wbmciIHdpZHRoPSI0MDBweCIgLz4KCiMjIyA8aHR0cDovL2Jvb3Rzd2F0Y2guY29tLz4KCioqKgoKPGJyPgoKIyAqKm1kIGJhc2ljcyoqCgo8YnI+CgojIyAqKnRleHQqKgoKICAgICAgICBub3JtYWwgdGV4dApub3JtYWwgdGV4dAoKICAgICAgICAqaXRhbGljIHRleHQqCippdGFsaWMgdGV4dCoKCiAgICAgICAgKipib2xkIHRleHQqKgoqKmJvbGQgdGV4dCoqCgogICAgICAgICoqKmJvbGQgaXRhbGljIHRleHQqKioKKioqYm9sZCBpdGFsaWMgdGV4dCoqKgoKICAgICAgICBzdXBlcnNjcmlwdF4yXgpzdXBlcnNjcmlwdF4yXgoKICAgICAgICB+fnN0cmlrZXRocm91Z2h+fgp+fnN0cmlrZXRocm91Z2h+fiAKCjxicj4KCiMjICoqaGVhZGVycyoqCgohW10oYXNzZXRzL2hlYWRlcnMucG5nKQoKIyMgKip1bm9yZGVyZWQgbGlzdHMqKgoKIVtdKGFzc2V0cy9idWxsZXRzLnBuZykKCiMjICoqb3JkZXJlZCBsaXN0cyoqCgohW10oYXNzZXRzL251bWJlcmVkLnBuZykKCiMjICoqcXVvdGVzICYgY29kZSoqCgogICAgPiB0aGlzIHRleHQgd2lsbCBiZSBxdW90ZWQKICAgCiA+ICoqdGhpcyB0ZXh0IHdpbGwgYmUgcXVvdGVkKioKIAogICAgYHRoaXMgdGV4dCB3aWxsIGFwcGVhciBhcyBjb2RlYCBpbmxpbmUKCmB0aGlzIHRleHQgd2lsbCBhcHBlYXIgYXMgY29kZWAgaW5saW5lCgoKYGBge3J9CmEgPC0gMTAKYGBgCgogICAgICAgIHRoZSB2YWx1ZSBvZiBwYXJhbWV0ZXIgKmEqIGlzIGByIGFgCgp0aGUgdmFsdWUgb2YgcGFyYW1ldGVyICphKiBpcyBgciBhYAoKPGJyPgoKIyMgKippbWFnZXMqKgoKICAgICAgICAhW10oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vd3AtY29udGVudC91cGxvYWRzLzIwMTUvMDEvcm1hcmtkb3duLWNoZWF0c2hlZXQtMi1lMTQ1NzYyNzU3ODgxNC5wbmcpCiAgICAgICAgCiAgICAgICAgIVtdKGFzc2V0cy9jaGVhdC5wbmcpCiAgICAgICAgCiFbXShhc3NldHMvY2hlYXQucG5nKQoKIyMKCiMjIyAqKnJlc2l6ZSBpbWFnZXMqKgoKICAgICAgICA8aW1nIHNyYz0iYXNzZXRzL2NoZWF0LnBuZyIgd2lkdGg9IjIwMHB4IiAvPgoKPGltZyBzcmM9ImFzc2V0cy9jaGVhdC5wbmciIHdpZHRoPSIyMDBweCIgLz4KCiMjICoqYmFzaWMgdGFibGVzKioKCiAgICBUYWJsZSBIZWFkZXIgIHwgU2Vjb25kIEhlYWRlcgogICAgLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0KICAgIENlbGwgMSAgICAgICAgfCBDZWxsIDIKICAgIENlbGwgMyAgICAgICAgfCBDZWxsIDQgCgpUYWJsZSBIZWFkZXIgIHwgU2Vjb25kIEhlYWRlcgotLS0tLS0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLQpDZWxsIDEgICAgICAgIHwgQ2VsbCAyCkNlbGwgMyAgICAgICAgfCBDZWxsIDQgCgpbKipvbmxpbmUgLm1kIHRhYmxlIGNvbnZlcnRlcioqXShodHRwOi8vd3d3LnRhYmxlc2dlbmVyYXRvci5jb20vbWFya2Rvd25fdGFibGVzKQoKPGJyPgoKIyMgKipsaW5rcyoqCgogICAgW0Rvd25sb2FkIFJdKGh0dHA6Ly93d3cuci1wcm9qZWN0Lm9yZy8pICAgIAogICAgW1JTdHVkaW9dKGh0dHA6Ly93d3cucnN0dWRpby5jb20vKQogICAgCgpbRG93bmxvYWQgUl0oaHR0cDovL3d3dy5yLXByb2plY3Qub3JnLykgICAgCgpbUlN0dWRpb10oaHR0cDovL3d3dy5yc3R1ZGlvLmNvbS8pCgo8YnI+CgojIyAqKmAubWRgIHJlc291cmNlcyoqCgo8c21hbGxlcj4KW29mZmljYWwgbWFya2Rvd24gZG9jdW1lbnRhdGlvbl0oaHR0cDovL2RhcmluZ2ZpcmViYWxsLm5ldC9wcm9qZWN0cy9tYXJrZG93bi9iYXNpY3MpCgpbUm1hcmtkb3duIGRvY3VtZW50YXRpb25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20vKQoKW1JzdHVkaW8gUm1hcmtkb3duIGNoZWF0c2hlZXRdKGh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3dwLWNvbnRlbnQvdXBsb2Fkcy8yMDE1LzAyL3JtYXJrZG93bi1jaGVhdHNoZWV0LnBkZikKCiAgICAKW2dpdGh1Yi5pbyB3ZWJzaXRlczogZWcgQW5keSBTb3V0aCdzIGJsb2ddKGh0dHA6Ly9hbmR5c291dGguZ2l0aHViLmlvL2Jsb2ctc2V0dXAvKQoKW1JlcHJvZHVjaWJsZSBSZXNlYXJjaF0oaHR0cHM6Ly93d3cuY291cnNlcmEub3JnL2xlYXJuL3JlcHJvZHVjaWJsZS1yZXNlYXJjaCkgY291cnNlcmEgTU9PQwoKW1Byb2R1Y2luZyBodG1sIGRvY3VtZW50cyBmcm9tIGAuUmAgc2NyaXB0cyB1c2luZyBga25pdHI6OnNwaW5gXShodHRwOi8vZGVhbmF0dGFsaS5jb20vMjAxNS8wMy8yNC9rbml0cnMtYmVzdC1oaWRkZW4tZ2VtLXNwaW4vKQoKPC9zbWFsbGVyPgoKIyAqKmNodW5rcyoqCgojIwoKUiBjb2RlIGNodW5rcyBjYW4gYmUgdXNlZCBhcyBhIG1lYW5zIHJlbmRlciBSIG91dHB1dCBpbnRvIGRvY3VtZW50cyBvciB0byBzaW1wbHkgZGlzcGxheSBjb2RlIGZvciBpbGx1c3RyYXRpb24KCjxpbWcgc3JjPSJhc3NldHMvbWFya2Rvd25DaHVuay5wbmciIHdpZHRoPSI1MDBweCIvPgoKCiMjICoqb3B0aW9ucyoqCgo8aW1nIHNyYz0iYXNzZXRzL2NodW5rcy5wbmciIHdpZHRoPSI1MDBweCIvPgoKZm9yIG1vcmUgZGV0YWlscyBzZWUgPGh0dHA6Ly95aWh1aS5uYW1lL2tuaXRyLz4KCiMjICoqc2V0IGRlZmF1bHQgb3B0aW9ucyoqCgpgYGB7ciwgZXZhbD1UUlVFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGLCBtZXNzYWdlID0gRikKYGBgCgoqKioKPGJyPgoKIyAqKmV4dHJhcyoqCgojIyAqKmBrbml0cjo6a2FibGUoKWAgdGFibGVzKioKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpyZXF1aXJlKGtuaXRyKQpkYXRhKGFpcnF1YWxpdHkpCmthYmxlKGhlYWQoYWlycXVhbGl0eSksIGNhcHRpb24gPSAiTmV3IFlvcmsgQWlyIFF1YWxpdHkgTWVhc3VyZW1lbnRzIikKYGBgCgo8YnI+CgojIyAqKmBEVDo6ZGF0YXRhYmxlKClgIHRhYmxlcyoqCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQpyZXF1aXJlKERUKQpkYXRhKGFpcnF1YWxpdHkpCmRhdGF0YWJsZShhaXJxdWFsaXR5LCBjYXB0aW9uID0gIk5ldyBZb3JrIEFpciBRdWFsaXR5IE1lYXN1cmVtZW50cyIpCmBgYAoKPGJyPgoKIyMgKipbcGxvdGx5XShodHRwczovL3Bsb3QubHkvKSoqCgpgYGB7ciwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZXZhbD1GQUxTRX0KbGlicmFyeShwbG90bHkpCgpzZXQuc2VlZCgxMDApCmQgPC0gZGlhbW9uZHNbc2FtcGxlKG5yb3coZGlhbW9uZHMpLCAxMDAwKSwgXQoKcCA8LSBnZ3Bsb3QoZGF0YSA9IGQsIGFlcyh4ID0gY2FyYXQsIHkgPSBwcmljZSkpICsKICBnZW9tX3BvaW50KGFlcyh0ZXh0ID0gcGFzdGUoIkNsYXJpdHk6IiwgY2xhcml0eSkpLCBzaXplID0gMSkgKwogIGdlb21fc21vb3RoKGFlcyhjb2xvdXIgPSBjdXQsIGZpbGwgPSBjdXQpKSArIGZhY2V0X3dyYXAofiBjdXQpCgpnZ3Bsb3RseShwKQoKYGBgCgojIyAKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD04LjN9CmxpYnJhcnkocGxvdGx5KQoKc2V0LnNlZWQoMTAwKQpkIDwtIGRpYW1vbmRzW3NhbXBsZShucm93KGRpYW1vbmRzKSwgMTAwMCksIF0KCnAgPC0gZ2dwbG90KGRhdGEgPSBkLCBhZXMoeCA9IGNhcmF0LCB5ID0gcHJpY2UpKSArCiAgZ2VvbV9wb2ludChhZXModGV4dCA9IHBhc3RlKCJDbGFyaXR5OiIsIGNsYXJpdHkpKSwgc2l6ZSA9IDEpICsKICBnZW9tX3Ntb290aChhZXMoY29sb3VyID0gY3V0LCBmaWxsID0gY3V0KSkgKyBmYWNldF93cmFwKH4gY3V0KQoKZ2dwbG90bHkocCkKCmBgYAoKPGJyPgoKIyMgKipzaGlueSoqCgo8aW1nIHNyYz0iYXNzZXRzL3NoaW55LnBuZyIgd2lkdGg9IjUwMHB4Ii8+CgojIyMgPGh0dHA6Ly9zaGlueS5yc3R1ZGlvLmNvbS8+Cgo8YnI+CgojIyAqKnJwdWJzKioKCiMjIyA8aHR0cDovL3JwdWJzLmNvbS8+Cgo8aW1nIHNyYz0iYXNzZXRzL3JwdWJzLnBuZyIgd2lkdGg9IjEwMHB4IiAvPgo8aW1nIHNyYz0iYXNzZXRzL3JwdWJzX3VpLmpwZyIgd2lkdGg9IjQwMHB4IiAvPgoKKioqCgo8YnI+CgoKIyAqKkV4ZXJjaXNlKioKCiMjICoqeW91ciBtaXNzaW9uKioKCj4gKmNyZWF0ZSB5b3VyIGZpcnN0IGAuUm1kYCEqCgotIGNob29zZSBzb21lIGRhdGEgZWc6IAogICAgKyBbYGRhdGFzZXRzYF0oaHR0cHM6Ly9zdGF0LmV0aHouY2gvUi1tYW51YWwvUi1kZXZlbC9saWJyYXJ5L2RhdGFzZXRzL2h0bWwvMDBJbmRleC5odG1sKSBwYWNrYWdlIAogICAgKyBgZGF0YShwYWNrYWdlID0gLnBhY2thZ2VzKGFsbC5hdmFpbGFibGUgPSBUUlVFKSlgCiAgICArIFtDYXJvbGluZSBUaG9tc29uJ3MgYmx1ZSB0aXQgZGF0YV0oaHR0cHM6Ly9vc2YuaW8vbjNqZ3kvKQotIHNob3cgdXMgc29tZSBkYXRhIGluIGEgdGFibGUKLSBwbG90IHNvbWUgZGF0YQotIHdyaXRlIGEgYml0IGFib3V0IHdoYXQgeW91IGRpZAotIHB1Ymxpc2ggaXQgb24gcnB1YnMuIEFkZCB5b3UgbGluayB0byBvdXIgW2dvb2dsZWRvY10oaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZG9jdW1lbnQvZC8xOEJGNFphbEdDTFlTbUZHU3NSMmtTaTBWcGw3NnNDWlhQTUtrUXMwU0t0US9lZGl0P3VzcD1zaGFyaW5nKQoKc2VlIG15IGV4YW1wbGU6ICoqYmVhdmVycyEqKiBbaHRtbF0oaHR0cDovL3JwdWJzLmNvbS9hbm5ha3J5c3RhbGxpLzIwMDExOSkgLSBbcmF3IC5SbWRdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9hbm5ha3J5c3RhbGxpL0lTQkVfc3ltcG9zaXVtL21hc3Rlci9tYXJrZG93bi9iZWF2ZXJzLlJtZCkKCgo=